
import org.apache.commons.codec.binary.Base64;
import util.Base64Utils;
import util.LoRaMacCrypto;
import util.Util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {
    public static byte[] key = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
    public static byte[] mickey = {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33};

    public static void main(String[] args) throws Exception {


        new Main().test3();
        System.out.println("------------------------------");
        System.out.println("------------------------------");
        System.out.println("------------------------------");

        new Main().test4();

    }
    // 解密
    public void test4() {
        byte[] bytes = Base64Utils.decode("YCIiIiKQAAABgIt7SM8=");
        // 看一下字节序列
        System.out.println("转16进制:" + Base64Utils.BytetoHex(bytes));

        byte dr = 0x01;
        // 密钥
        byte mhdr = bytes[0];
        // 设备节点address
        byte[] dev = new byte[4];
        System.arraycopy(bytes, 1, dev, 0, 4); //Object src,  int  srcPos, Object dest, int destPos, int length
        byte fCtrl = bytes[5];
        byte fPort = bytes[8];
        byte[] fcnt = {bytes[6], bytes[7], 0x00, 0x00}; // 校验码，小端：所有多字节字段的字节序均采用小端模式
        byte[] frmPaload = new byte[bytes.length - 9 - 4];
        byte[] genMicBody = new byte[10];
        System.arraycopy(bytes, 0, genMicBody, 0, 10);
        System.arraycopy(bytes, 9, frmPaload, 0, bytes.length - 9 - 4);
        fcnt = new byte[]{0x04, 0x00, 0x00, 0x00};
        System.out.println("解密后转16进制:" + Base64Utils.BytetoHex(LoRaMacCrypto.LoRaMacPayloadDecrypt(frmPaload, frmPaload.length, key, dev, dr, fcnt)));

        genMicBody[6] = 0x0a;
    }

    // 加密
    public void test3(byte[] cnt,byte[] data) throws Exception {
        byte dr = 0x01;
//        // 密钥
        byte mhdr = 0x60;
//
//        // 设备节点address
        byte[] dev = new byte[]{0x22,0x22,0x22,0x22};
        byte fCtrl = (byte) 0x90;
        byte[] fcnt = cnt; // 校验码，小端：所有多字节字段的字节序均采用小端模式
        byte fPort = 0x01;
        ByteBuffer byteBuffer= ByteBuffer.allocate(10);

//        // 设备节点address
        byte[] frmPaload = new byte[byteBuffer.array().length - 9 - 4];

        System.out.println("frmPaload:" + Base64Utils.BytetoHex(frmPaload));
        byte[] encrypted = LoRaMacCrypto.LoRaMacPayloadDecrypt(data, data.length, key, dev, dr, fcnt);
        System.out.println("新数据加密后转16进制:" + Base64Utils.BytetoHex(encrypted));
        byteBuffer.put(mhdr).put(dev).put(fCtrl).put(fcnt).put(fPort).put(encrypted);

//        byte[] fcnt = {0x21, 0x44, 0x3d, (byte) 0xcd}; // 校验码，小端：所有多字节字段的字节序均采用小端模式
//        frmPaload = new byte[0x01];
        System.arraycopy(byteBuffer.array(), 9, frmPaload, 0, byteBuffer.array().length - 9);
        System.out.println("加密后转16进制:" + LoRaMacCrypto.LoRaMacPayloadDecrypt(frmPaload, frmPaload.length, key, dev, dr, fcnt));
        byte[] micCnt = new byte[]{byteBuffer.array()[6], byteBuffer.array()[7], 0x00, 0x00};
        byte[] mic = LoRaMacCrypto.LoRaMacComputeMic(byteBuffer.array(), byteBuffer.array().length, mickey, dev, dr, micCnt);
        System.out.println("Base64Utils.BytetoHex(mic) = " + Base64Utils.BytetoHex(mic));
        System.out.println("byteBuffer.array() = " + Base64Utils.BytetoHex(byteBuffer.array()));
        String base64des = Base64Utils.encode(byteBuffer.array());
        System.out.println("base64des = " + base64des);
        System.out.println("Context = " + Base64Utils.encode(new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}));
    }

    public void test2() throws UnsupportedEncodingException {
        byte[] bytes1 = Base64.decodeBase64("a04KZJuYQfqiFqfOXKIilQ==");

        System.out.println("!" + new String(bytes1, "gbk"));
        for (byte b : bytes1) {
            System.out.print((char) b);
        }

    }

    public void test1() throws Exception {
        // 数据帧的加解密检验, 上行
        byte[] frmdata = {(byte) 0x0f, 0x0f, (byte) 0x0f, (byte) 0x0f};
        byte[] appsk = {0x73, 0x5f, 0x4f, (byte) 0xf8, (byte) 0xe2,
                (byte) 0xb5, 0x53, (byte) 0xc8, (byte) 0xbf, (byte) 0x87, 0x5b, 0x37, (byte) 0x97, 0x09, 0x7f, (byte) 0x85};
        byte[] ad = {(byte) 0xca, 0x67, 0x73, 0x02};
        byte[] sq = {0x00, 0x00, 0x00, 0x00};


        byte dr = 0x00;
        String data = "QCIiIiKAZwABu8RiHbqwavcQJF5VkSbEeM9t7cs9FQuz8rS4rucRfS2szJiuhGspUAsnMonVGfi5og==";
        byte[] bytes = Base64.decodeBase64(data);
        String s = Base64Utils.BytetoHex(bytes);
        System.out.println("base64:" + s);
        bytes = new byte[]{
                (byte) 0xbb, (byte) 0xc4, (byte) 0x62, (byte) 0x1d, (byte) 0xba, (byte) 0xb0, (byte) 0x6a, (byte) 0xf7, (byte) 0x10,
                (byte) 0x24, (byte) 0x5e, (byte) 0x55, (byte) 0x91, (byte) 0x26, (byte) 0xc4, (byte) 0x78, (byte) 0xcf, (byte) 0x6d,
                (byte) 0xed, (byte) 0xcb, (byte) 0x3d, (byte) 0x15, (byte) 0x0b, (byte) 0xb3, (byte) 0xf2, (byte) 0xb4, (byte) 0xb8,
                (byte) 0xae, (byte) 0xe7, (byte) 0x11, (byte) 0x7d, (byte) 0x2d, (byte) 0xac, (byte) 0xcc, (byte) 0x98, (byte) 0xae,
                (byte) 0x84, (byte) 0x6b, (byte) 0x29, (byte) 0x50, (byte) 0x0b, (byte) 0x27, (byte) 0x32, (byte) 0x89, (byte) 0xd5,
        };
        System.out.println("byte:" + Arrays.toString(bytes));
        System.out.println("byte:" + bytes.length);

        byte[] key = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
        byte[] fcnt = {0x67, 0x00, 0x00, 0x00}; // 大端
        byte[] dev = {(byte) 0x22, 0x22, (byte) 0x22, 0x22};


//        byte[] outputaccept = LoRaMacCrypto.LoRaMacPayloadEncrypt(frmdata, frmdata.length, appsk, ad, dr, sq);

//        LoRaMacCrypto.myprintHex(outputaccept);
//        System.out.println("accept：AppSKey");
        LoRaMacCrypto.myprintHex(LoRaMacCrypto.LoRaMacPayloadDecrypt(bytes, bytes.length, key, dev, dr, fcnt));

    }
}
